<?php
namespace app\site\service;

use app\common\library\Service;

class Site extends Service
{
    use \app\common\library\traits\Model;
    protected $batchValidate = null;
    protected $modelValidate = null;

    protected function _initialize() {
        parent::_initialize();
        $this->model = model('site/Site');
    }
    /**
     * 站点列表
     * @param mixed $maps   查询条件
     * @return mixed
     */
    public function lists($maps = '', $order = 'create_time DESC', $page = 0, $limit = 12, $field = true, $relations = [], $attrs =[]) {
        $result = $this->model->order($order)->field($field);
        if (isset($maps['custom_id'])) {
            $result = $result->where('custom_id','=',$maps['custom_id']);
        }
        if (isset($maps['custom_ids'])) {
            $result = $result->where('custom_id|create_custom_id','=',$maps['custom_ids']);
        }
        if (!empty($maps['name'])){
            $result = $result->where('name','like','%'.$maps['name'].'%');
        }
        if (!empty($maps['create_time'])){
            $result = $result->whereTime('create_time',$maps['create_time']);
        }
        if (!empty($maps['deadline'])){
            $result = $result->whereTime('deadline',$maps['deadline']);
        }

        if($page !== false) {
            $result = $result->paginate($limit, '', ['page' => $page]);
        } else {
            $result = $result->limit($limit)->select();
        }

        /* 关联数据获取 */
        if(!empty($relations)) {
            foreach ($result as $key => $value) {
                array_map(function($e) use (&$value) {
                    $e = trim($e);
                    $value->$e = $value->$e ?: new \stdClass(); // 注意没有数据不要返回默认的 NULL
                }, $relations);
            }
        }

        /* 获取器数据 */
        if(!empty($attrs)) {
            foreach ($result as $key => $value) {
                array_map(function($attr) use (&$value) {
                    $attr = trim($attr);
                    return $value->$attr = $value->getAttr($attr);
                }, $attrs);
            }
        }
        return $result;
    }
    /**
     * [create 创建]
     * @param  string  $name      [description]
     * @param  string  $deadline  [description]
     * @param  integer $custom_id [description]
     * @return [type]             [description]
     */
    public function create($name = '',$count_type = '',$number = 0,$type = ['baidu'],$custom_id = '',$current_custom_id = '',$desc = '',$app_id = '',$app_key = '',$app_secret = '',$style_id = 1){
        if(empty($count_type) || !in_array($count_type, ['month','quarter','year','forever'])){
            $this->error = '开通时长类型有误';
            return false;
        }
        if(in_array($count_type,['month','quarter','year']) && (int) $number < 1){
            $this->error = '开通时长有误';
            return false;
        }
        $renewline = 0;
        $time = 0;
        switch ($count_type) {
            case 'month':
                $renewline = strtotime('+'.$number.' month');
                $time = $number;
                break;
            case 'quarter':
                $renewline = strtotime('+'.(3*$number).' month');
                $time = $number * 3;
                break;
            case 'year':
                $renewline = strtotime('+'.$number.' year');
                $time = $number * 12;
                break;
            case 'forever':
                $renewline = 0;
                break;
            default:
                break;
        }
        //计算过期时间
        $deadline = $count_type == 'forever' ? 0 : $renewline;
        //此处为全站设置中的价格
        $fee = \app\admin\model\Config::where('key','=','fee_create_'.$count_type)->value('value');
        $total_fee = $count_type == 'forever' ? $fee : $fee * $number;
        \Db::startTrans();
        try {
            $deduction = model('custom/Custom','service')->deduction($current_custom_id,$total_fee,'开通站点');
            if($deduction === false) throw new \Exception(model('custom/Custom','service')->getError());
            $id = \fast\Uuid::create();
            $token = md5($id.\fast\Random::numeric(6));
            $result = $this->model->create(['id' => $id,'token' => $token,'name' => $name,'custom_id' => $custom_id,'create_custom_id' => $current_custom_id,'deadline' => $deadline,'desc' => $desc,'status' => 1,'type' => $type,'time' => $time]);
            //写入配置
            $setting = $this->setting($id,$custom_id,$app_id,$app_key,$app_secret,'baidu',$style_id);
            if($setting === false) throw new \Exception($this->error);
            //写入操作表
            $r = model('site/SiteOperate','service')->create($id,'create',$current_custom_id,$count_type,$number,$deduction->log_id);
            if($r === false) throw new \Exception(model('site/SiteOperate','service')->getError());
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            \Db::rollback();
            return false;
        }
        \Db::commit();
        return $result;
    }
    /**
     * [edit 编辑]
     * @param  [type]  $info      [description]
     * @param  integer $custom_id [description]
     * @return [type]             [description]
     */
    public function edit($info = [],$custom_id = ''){
        if(empty($info['id'])){
            $this->error = '站点标识不能为空';
            return false;
        }
        $site = $this->model->find($info['id']);
        if($site['custom_id'] != $custom_id && $site['create_custom_id'] != $custom_id){
            $this->error = '没有权限操作';
            return false;
        }
        \Db::startTrans();
        try {
            $result = $site->allowField(['name','token','desc','status','custom_id','logo','phone'])->save($info);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            \Db::rollback();
            return false;
        }
        \Db::commit();
        return $site;
    }
    /**
     * [delete 删除]
     * @param  string  $id        [description]
     * @param  integer $custom_id [description]
     * @return [type]             [description]
     */
    public function delete($id = '',$custom_id = '',$is_force = 0){
        if(empty($id)){
            $this->error = '站点标识不能为空';
            return false;
        }
        $site = $this->model->find($id);
        if($site['custom_id'] != $custom_id){
            $this->error = '没有权限操作';
            return false;
        }
        \Db::startTrans();
        try {
            $result = $site->delete();
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            \Db::rollback();
            return false;
        }
        \Db::commit();
        return $result;
    }
    /**
     * [详情]
     * @param  string  $id        [description]
     * @param  integer $custom_id [description]
     * @return [type]             [description]
     */
    public function detail($id = '',$custom_id = ''){
        \Db::startTrans();
        try {
            if(empty($id)){
                $this->error = '站点标识不能为空';
                return false;
            }
            $site = $this->model->find($id);
            $setting = model('site/SiteSetting')->where('site_id','=',$id)->find();
            $site['appid'] = $setting['appid'];
            $site['app_key'] = $setting['app_key'];
            $site['app_secret'] = $setting['app_secret'];
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            \Db::rollback();
            return false;
        }
        \Db::commit();
        return $site;
    }
    /**
     * [renew 续费]
     * @param  string  $id        [description]
     * @param  integer $custom_id [description]
     * @param  integer $type [续费类型（按月、季度、年、永久）]
     * @return [type]             [description]
     */
    public function renew($id = '',$custom_id = '',$type = '',$number = 0){
        if(empty($custom_id)){
            $this->error = '客户信息有误';
            return false;
        }
        if(empty($id)){
            $this->error = '站点信息有误';
            return false;
        }
        if(empty($type) || !in_array($type, ['month','quarter','year','forever'])){
            $this->error = '续费类型有误';
            return false;
        }
        if(in_array($type,['month','quarter','year']) && (int) $number < 1){
            $this->error = '续费时长有误';
            return false;
        }
        //查询上级
        $site = $this->model->find($id);
        if(empty($site)){
            $this->error = '站点不存在';
            return false;
        }
        if($site['status'] == -1){
            $this->error = '该站点已被禁用，无法续费';
            return false;
        }
        if($site['deadline'] == 0){
            $this->error = '该站点使用期为永久，无需续费';
            return false;
        }
        //此处为全站设置中的价格
        $fee = \app\admin\model\Config::where('key','=','fee_renew_'.$type)->value('value');
        //续费
        $renewline = 0;
        $time = 0;
        switch ($type) {
            case 'month':
                $renewline = strtotime('+'.$number.' month',$site->deadline);;
                $time = $number;
                break;
            case 'quarter':
                $renewline = strtotime('+'.(3*$number).' month',$site->deadline);
                $time = $number * 3;
                break;
            case 'year':
                $renewline = strtotime('+'.$number.' year',$site->deadline);
                $time = $number * 12;
                break;
            case 'forever':
                $renewline = 0;
                break;
            default:
                break;
        } 
        $site->deadline = $renewline;
        $site->time = $type == 'forever' ? 0 : $site->time + $time;
        $total_fee = $type == 'forever' ? $fee : $fee * $number;
        \Db::startTrans();
        try{
            //从余额中扣除,余额不足提示充值
            $result = model('custom/Custom','service')->deduction($custom_id,$total_fee,'站点续费');
            if($result === false) throw new \Exception(model('custom/Custom','service')->getError());
            //更新截止时间
            $site->save();
            //写入站点操作表
            $r = model('site/SiteOperate','service')->create($id,'renew',$custom_id,$type,$number,$result->log_id);
            if($r === false) throw new \Exception(model('site/SiteOperate','service')->getError());
        }catch(\Exception $e){
            $this->error = $e->getMessage();
            \Db::rollback();
            return false;
        }
        \Db::commit();
        return $site;
    }
    /**
     * [setting 配置]
     * @param  string $id         [description]
     * @param  string $custom_id  [description]
     * @param  string $app_id     [description]
     * @param  string $app_key    [description]
     * @param  string $app_secret [description]
     * @return [type]             [description]
     */
    public function setting($id = '',$custom_id = '',$appid = '',$app_key = '',$app_secret = '',$type = '',$template_id = 1){
        $model = model('site/SiteSetting');
        $info = [
            'appid' => $appid,
            'app_key' => $app_key,
            'app_secret' => $app_secret,
            'site_id' => $id,
            'custom_id' => $custom_id,
            'type' => $type,
            'style_id' => $template_id
        ];
        $isupdate = false;
        $site = $model->where('site_id','=',$id)->where('type','=',$type)->find();
        if(!empty($site)){
            $info['id'] = $site['id'];
            $isupdate = true;
        }
        \Db::startTrans();
        try {
            $result = $model->save($info,$isupdate);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            \Db::rollback();
            return false;
        }
        \Db::commit();
        return $result;
    }
    /**
     * [download 下载小程序]
     * @param  string $id        [description]
     * @param  string $custom_id [description]
     * @return [type]            [description]
     */
    public function download($id = '',$custom_id = '',$type = ''){
        $model = model('site/SiteSetting');
        if(empty($custom_id)){
            $this->error = '客户信息有误';
            return false;
        }
        if(empty($id)){
            $this->error = '站点信息有误';
            return false;
        }
        $site = $model->where('custom_id','=',$custom_id)->where('site_id','=',$id)->where('type','=',$type)->find();
        if(empty($site)){
            $this->error = '没有权限下载';
            return false;
        }
        //复制前端文件,以type、站点id
        $upload_path = \Env::get('root_path').'uploadfile/';
        if(!is_dir($upload_path)){
            $this->error = '代码存放目录不存在，请联系管理员';
            return false;
        }
        $source = $upload_path.$type;
        if(!is_dir($source)){
            $this->error = '代码存放目录不存在，请联系管理员';
            return false;
        }
        $config_path = $upload_path.'config/'.$type.'/';
        if(!is_dir($config_path)){
            $this->error = '代码存放目录不存在，请联系管理员';
            return false;
        }
        try{
            //检查是否存在config.js文件，存在则删除
            $config_file = $source.'/libs/config.js';
            if(is_file($config_file) && file_exists($config_file)){
                @unlink($config_file);
            }
            $app_json = $source.'/app.json';
            if(is_file($app_json) && file_exists($app_json)){
                @unlink($app_json);
            }
            $swan_json = $source.'/project.swan.json';
            if(is_file($swan_json) && file_exists($swan_json)){
                @unlink($swan_json);
            }
            $template_css = $source.'/template/template.css';
            if(is_file($template_css) && file_exists($template_css)){
                @unlink($template_css);
            }
            switch ($type) {
                case 'baidu':
                    //替换api
                    $config_file_content = file_get_contents($config_path.'config.js');
                    $config_file_content = str_replace(['{{api}}','{{token}}','{{type}}'], [\think\facade\Env::get('api.url', ''),$site->site_info->token,$type], $config_file_content);
                    file_put_contents($config_file, $config_file_content);
                    //替换appid配置
                    $app_json_content = file_get_contents($config_path.'app.json');
                    $app_json_content = str_replace('{{color}}',$site->template_info->theme['color'],$app_json_content);
                    file_put_contents($app_json, $app_json_content);
                    //替换模板
                    $swan_json_content = file_get_contents($config_path.'project.swan.json');
                    $swan_json_content = str_replace('{{appid}}',$site->appid,$swan_json_content);
                    file_put_contents($swan_json, $swan_json_content);
                    //替换css
                    $template_css_content = file_get_contents($config_path.'template.css');
                    $template_css_content = str_replace('{{color}}',$site->template_info->theme['color'],$template_css_content);
                    file_put_contents($template_css, $template_css_content);
                    break;
                
                default:
                    
                    break;
            }
            //生成config.js文件
            $zip = new \ZipArchive();  
            $user_filename = $type.'_'. $id.'.zip';
            $user_filepath = $upload_path.$type.'_'. $id.'.zip';
            if(!$zip->open($user_filepath,\ZIPARCHIVE::CREATE)){  
                $this->error = "创建[".$user_filepath."]失败<br/>";
                return false;  
            }  
            $this->createZip(opendir($source),$zip,$source);  
            $zip->close();
            @unlink($config_file); 
            @unlink($app_json);
            @unlink($swan_json);
            @unlink($template_css);
        }catch(\Exception $e){
            $this->error = $e->getMessage();
            return false;
        }
        return ['downname' => $user_filename,'filepath' => $user_filepath];
    }
    /**
     * [valid_site description]
     * @param  string $site_id   [description]
     * @param  string $custom_id [description]
     * @param  string $type      [description]
     * @return [type]            [description]
     */
    public function valid_site($site_id = '',$custom_id = '',$type = ''){
        $model = model('site/SiteSetting');
        if(empty($custom_id)){
            $this->error = '客户信息有误';
            return false;
        }
        if(empty($site_id)){
            $this->error = '站点信息有误';
            return false;
        }
        $site = $model->where('custom_id','=',$custom_id)->where('site_id','=',$site_id)->where('type','=',$type)->find();
        if(empty($site) || empty($site['appid'] || empty($site['app_key'] || empty($site['app_secret'])))){
            $this->error = '请先完善小程序配置';
            return false;
        }
        return true;
    }
    /**
     * [createZip description]
     * @param  [type] $openFile   [description]
     * @param  [type] $zipObj     [description]
     * @param  [type] $sourceAbso [description]
     * @param  string $newRelat   [description]
     * @return [type]             [description]
     */
    public function createZip($openFile,$zipObj,$sourceAbso,$newRelat = '')  
    {  
        while(($file = readdir($openFile)) != false)  
        {  
            if($file=="." || $file=="..")  
                continue;  
              
            /*源目录路径(绝对路径)*/  
            $sourceTemp = $sourceAbso.'/'.$file;  
            /*目标目录路径(相对路径)*/  
            $newTemp = $newRelat==''?$file:$newRelat.'/'.$file;  
            if(is_dir($sourceTemp))  
            {  
                //echo '创建'.$newTemp.'文件夹<br/>';  
                $zipObj->addEmptyDir($newTemp);/*这里注意：php只需传递一个文件夹名称路径即可*/  
                $this->createZip(opendir($sourceTemp),$zipObj,$sourceTemp,$newTemp);  
            }  
            if(is_file($sourceTemp))  
            {  
                //echo '创建'.$newTemp.'文件<br/>';  
                $zipObj->addFile($sourceTemp,$newTemp);  
            }  
        }  
    }  
    /**
     * [get_token 获取token]
     * @param  string $site_id [description]
     * @return [type]          [description]
     */
    public function get_token($site_id = '')
    {
        if(empty($site_id)){
            $this->error = '站点标识不能为空';
            return false;
        }
        $token = md5($site_id.\fast\Random::numeric(6));
        return $token;
    }
    /**
     * [get_renew_fee 获取续费金额]
     * @param  string  $site_id [description]
     * @param  string  $type    [description]
     * @param  integer $number  [description]
     * @return [type]           [description]
     */
    public function get_renew_fee($type = 'forever',$number = 0,$custom_id = ''){
        if(empty($type) || !in_array($type, ['month','quarter','year','forever'])){
            $this->error = '开通时长类型有误';
            return false;
        }
        if(in_array($type,['month','quarter','year']) && (int) $number < 1){
            $this->error = '开通时长有误';
            return false;
        }
        $fee = \app\admin\model\Config::where('key','=','fee_renew_'.$type)->value('value');
        if(is_null($fee)){
            $this->error = '消费类型不存在';
            return false;
        }
        $total_fee = $type == 'forever' ? $fee : $fee * $number;
        return $total_fee;
    }
    /**
     * [get_create_fee description]
     * @param  string  $type      [description]
     * @param  integer $number    [description]
     * @param  string  $custom_id [description]
     * @return [type]             [description]
     */
    public function get_create_fee($type = 'forever',$number = 0,$custom_id = ''){
        if(empty($type) || !in_array($type, ['month','quarter','year','forever'])){
            $this->error = '开通时长类型有误';
            return false;
        }
        if(in_array($type,['month','quarter','year']) && (int) $number < 1){
            $this->error = '开通时长有误';
            return false;
        }
        $fee = \app\admin\model\Config::where('key','=','fee_create_'.$type)->value('value');
        if(is_null($fee)){
            $this->error = '消费类型不存在';
            return false;
        }
        $total_fee = $type == 'forever' ? $fee : $fee * $number;
        return $total_fee;
    }
    /**
     * [template description]
     * @param  string  $site_id   [description]
     * @param  integer $style_id   [description]
     * @param  string  $custom_id [description]
     * @return [type]             [description]
     */
    public function template($site_id = '',$style_id = 0,$type = 'baidu',$custom_id = ''){
        $model = model('site/SiteSetting');
        if(empty($custom_id)){
            $this->error = '客户信息有误';
            return false;
        }
        if(empty($site_id)){
            $this->error = '站点信息有误';
            return false;
        }
        $model = model('site/SiteSetting');
        $info = [
            'style_id' => $style_id,
            'site_id' => $site_id,
            'custom_id' => $custom_id,
            'type' => $type
        ];
        $isupdate = false;
        $site = $model->where('site_id','=',$site_id)->where('type','=',$type)->find();
        if(!empty($site)){
            $info['id'] = $site['id'];
            $isupdate = true;
        }
        \Db::startTrans();
        try {
            $result = $model->save($info,$isupdate);
        } catch (\Exception $e) {
            $this->error = $e->getMessage();
            \Db::rollback();
            return false;
        }
        \Db::commit();
        return $result; 
    }
}